package cn.tedu.charging.cost.service.impl;


import cn.tedu.charging.common.pojo.param.ChargingProcessParam;
import cn.tedu.charging.common.pojo.vo.ChargingProcessVO;
import cn.tedu.charging.cost.dao.repository.CostRuleRepository;
import cn.tedu.charging.cost.pojo.po.CostRulePO;
import cn.tedu.charging.cost.service.CostService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Service
@Slf4j
public class CostServiceImpl implements CostService {
    @Override
    public ChargingProcessVO calculateCost(ChargingProcessParam chargingProcessParam) {


        Integer currentHour = getCurrentHour();
        log.debug("获取当前时间小时:{}", currentHour);
        Integer stationId = chargingProcessParam.getStationId();
        Integer gunType = chargingProcessParam.getGunType();
        CostRulePO costRulePO = getMatchCostRuleByGunTypeAndTime(stationId, gunType, currentHour);
        log.debug("通过场站id：{} ,枪类型:{}, " +
                "时间：{}获取匹配的计费规则:{}",
                stationId, gunType,
                currentHour ,costRulePO);

        if (costRulePO != null) {
            String name = costRulePO.getName();

            BigDecimal powerFee = costRulePO.getPowerFee();

            Float chargingCapacity = chargingProcessParam.getChargingCapacity();

            BigDecimal cost = getCost(chargingCapacity, powerFee);

            log.debug("当前时间:{},计价规则的名称:{}," +
                    "充电的单价:{}, 充电度数:{}," +
                    "本次花费:{}, 总花费:{}",
                    currentHour, name,
                    powerFee, chargingCapacity,
                    cost,cost);
        }else {
            log.error("故障计价规则为空，进行系统告警，业务停止");
        }


        ChargingProcessVO chargingProcessVO = new ChargingProcessVO();
        chargingProcessVO.setOrderNo(chargingProcessParam.getOrderNo());
        chargingProcessVO.setGunId(chargingProcessParam.getGunId());
        return chargingProcessVO;
    }

    private BigDecimal getCost(Float chargingCapacity, BigDecimal powerFee) {
        //1>通过构造器 进行类型转换
        //Float 转换为 BigDecimal
        //BigDecimal bigDecimal = new BigDecimal(chargingCapacity);
        //基本类型的数字转换为 包装类型的 Integer
        //Integer i = new Integer(1);
        //String 转换为 包装类型的 String
        //String s = new String("1");

        //2>通过方法 进行类型转换 valueOf
        //通过方法 valueOf 转换 float 转为 String
        //String s = String.valueOf(chargingCapacity);
        //Float 转换为 BigDecimal
        BigDecimal bigDecimal = BigDecimal.valueOf(chargingCapacity);
        //BigDecimal add 加计算  multiply 乘法
        return powerFee.multiply(bigDecimal);
    }


    private Integer getCurrentHour() {
        LocalDateTime now = LocalDateTime.now();
        return now.getHour();
    }

    /**
     * 通过时间 和 枪类型 匹配一个计价规则
     * @param stationId
     * @param gunType
     * @param hour
     * @return
     */
    private CostRulePO getMatchCostRuleByGunTypeAndTime(
            Integer stationId,
            Integer gunType,
            Integer hour) {
        log.debug("通过场站id：{}获取计价规则列表", stationId);
        List<CostRulePO> costRules = getCostRule(stationId);
//        CostRulePO costRule = costRuleRepository.getMatchCostRule(stationId, gunType, hour);
        log.debug("通过场站id：{}获取的计价规则列表:{}",stationId , costRules);
        //判断计价规则列表是否为空
        if (!CollectionUtils.isEmpty(costRules)){

//            Optional<CostRulePO> first = costRules.stream().filter(e -> e.getGunType().equals(gunType)
//                    && hour >= e.getStartTime()
//                    && hour < e.getEndTime()).findFirst();
//
//            if (first.isPresent()){
//                return first.get();
//            }

            for (CostRulePO costRule : costRules) {
                //判断枪类型是否匹配
                Integer costRuleGunType = costRule.getGunType();
                if (costRuleGunType.equals(gunType)) {
                    //获取计价的开始时间
                    Integer startTime = costRule.getStartTime();
                    //获取计价的结束时间
                    Integer endTime = costRule.getEndTime();
                    if (hour >= startTime && hour < endTime) {
                        return costRule;
                    }
                }
            }
        }
        //循环结束，没有匹配的规则，返回null
        return null;
    }

    @Autowired
    private CostRuleRepository costRuleRepository;
    private List<CostRulePO> getCostRule(Integer stationId) {
        List<CostRulePO> costRulePOS = costRuleRepository.getCostRuleByStationId(stationId);

        return costRulePOS;
    }
}
